﻿using Kingdee.BOS;
using Kingdee.BOS.App.Data;
using Kingdee.BOS.BusinessEntity.BillTrack;
using Kingdee.BOS.BusinessEntity.Login;
using Kingdee.BOS.Contracts;
using Kingdee.BOS.Core;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.ServiceHelper;
using Kingdee.BOS.Util;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using static LiMinCRMPlugin.InterfaceDocking.ReceivableMode;

namespace LiMinCRMPlugin.InterfaceDocking
{
    // <summary>
    /// 回调应收单未推送CRM接口
    /// </summary>
    /// <remarks>
    /// 功能：应收转销单生成的应收单定时上传，因为审核触发器不触发
    /// 创建人：mey
    /// 创建日期：2024年3月28日
    /// </remarks>
    [Description("回调应收单未推送CRM接口")]
    [Kingdee.BOS.Util.HotUpdate]
    public class ReceivablePlan : IScheduleService
    {
        public void Run(Context ctx, Schedule schedule)
        {


            //查询需要上传的信息
            var sql = @"/*dialect*/select * from t_AR_receivable a
               where  fSetAccountType='3' and fIsWriteOff='1' and F_DEV_FSTATUS<>'成功'";
            DataTable dt_Db = DBUtils.ExecuteDataSet(ctx, sql).Tables[0];
            foreach (DataRow ItemRow in dt_Db.Rows)
            {
                string FID = Convert.ToString(ItemRow["FId"]);//内码   
                FormMetadata meta = MetaDataServiceHelper.Load(
                 ctx, "AR_receivable") as FormMetadata;
                DynamicObject entity = BusinessDataServiceHelper.LoadSingle(ctx, FID, meta.BusinessInfo.GetDynamicObjectType());



                DataTable dt = APISetting(ctx);
                string httpUrl = dt.Rows[0]["F_RDLV_URL"].ToString();
                string httpSystemId = dt.Rows[0]["F_RDLV_SystemId"].ToString();
                string httpPassword = dt.Rows[0]["F_RDLV_Password"].ToString();

                #region  单据头信息
                string FSTATUS = Convert.ToString(entity["F_DEV_FSTATUS"]);//同步CRM状态 空-未同步，成功-同步成功，失败-同步失败

                string Number = entity["BillNo"].ToString();//编码

                string sfdc1 = entity["F_DEV_Survive"].ToString();//是否淡储 枚举：[0:否,1:是]
                string crmbm1 = entity["F_DEV_CRMNumber"].ToString();//CRM编码
                string ddbh1 = entity["F_DEV_OrderNo"].ToString();//订单编号


                DynamicObject FCreator = entity["CreatorId"] as DynamicObject;//销售员 
                string FCreator1 = "";
                if (FCreator != null)
                {
                    FCreator1 = Convert.ToString(FCreator["UserAccount"]);

                }

                FCreator1 = "CRM";
                DynamicObject FSaledep = entity["SALEDEPTID"] as DynamicObject;//销售部门 
                string xsbm1 = "";
                if (FSaledep != null)
                {
                    xsbm1 = Convert.ToString(FSaledep["Number"]);

                }
                DynamicObject FSaler = entity["F_DEV_Saler"] as DynamicObject;//销售员 
                string xsy1 = "";
                if (FSaler != null)
                {
                    xsy1 = Convert.ToString(FSaler["FStaffNumber"]);

                }
                DynamicObject FSALEORG = entity["SALEORGID"] as DynamicObject;//销售组织 
                string xszz1 = "";
                if (FSALEORG != null)
                {
                    xszz1 = Convert.ToString(FSALEORG["Number"]);

                }
                string rq1 = "";
                if (entity["DATE"] != null && entity["DATE"].ToString() != "")
                {
                    rq1 = Convert.ToDateTime(entity["DATE"]).ToString("yyyy-MM-dd");//业务日期 ywrq
                }

                string fhzz1 = "";//财务应收没有发货组织

                DynamicObject FSETTLEORG = entity["SETTLEORGID"] as DynamicObject;//结算组织 
                string jszz1 = "";
                if (FSETTLEORG != null)
                {
                    jszz1 = Convert.ToString(FSETTLEORG["Number"]);

                }

                DynamicObject PAYORGID = entity["FPAYORGID"] as DynamicObject;//收款组织 
                string skzz1 = "";
                if (PAYORGID != null)
                {
                    skzz1 = Convert.ToString(PAYORGID["Number"]);

                }




                DynamicObject FHeadLocation = entity["F_RDLV_HeadLocationId"] as DynamicObject;//交换地点 
                string jhdd1 = "";
                if (FHeadLocation != null)
                {
                    jhdd1 = Convert.ToString(FHeadLocation["Name"]);

                }
                string sfdhdd1 = entity["F_RDLV_Seasoning"].ToString();//是否淡储 枚举：[0:否,1:是]
                string bz1 = entity["REMARK"].ToString();//备注

                DynamicObject FCURRENCYID = entity["CURRENCYID"] as DynamicObject;//结算币别 
                string jsbb1 = "";
                if (FCURRENCYID != null)
                {
                    jsbb1 = Convert.ToString(FCURRENCYID["Name"]);

                }

                string sfdz1 = entity["F_DEV_Offset"].ToString();//是否定制   枚举：[0:否,1:是]

                DynamicObject HeadDeliveryWay = entity["F_RDLV_HeadDeliveryWay"] as DynamicObject;//交货方式  枚举：[0:发货,1:自提] 
                string jhfs1 = "";
                if (HeadDeliveryWay != null)
                {
                    jhfs1 = Convert.ToString(HeadDeliveryWay["FDataValue"]);

                    if (jhfs1 == "发货")
                        jhfs1 = "0";
                    else
                    if (jhfs1 == "自提")
                        jhfs1 = "1";
                    else
                        jhfs1 = "0";
                }

                DynamicObject FCUSTOMERID = entity["CUSTOMERID"] as DynamicObject;//客户 
                string khmc1 = "";
                if (FCUSTOMERID != null)
                {
                    khmc1 = Convert.ToString(FCUSTOMERID["Number"]);

                }


                if (khmc1 != "")
                {
                    string payUnit_S = string.Format(@"/*dialect*/  select * from T_BD_CUSTOMER where FNUMBER='" + khmc1 + "'");
                    DataTable dt_S = DBServiceHelper.ExecuteDataSet(ctx, payUnit_S).Tables[0];//F_DEV_CRMId
                    if (dt_S != null && dt_S.Rows.Count > 0)
                    {
                        khmc1 = dt_S.Rows[0]["F_RDLV_CRMId"].ToString();
                    }


                }



                DynamicObject FPayConditon = entity["PayConditon"] as DynamicObject;//收款条件 
                string sktj1 = "";
                if (FPayConditon != null)
                {
                    sktj1 = Convert.ToString(FPayConditon["Number"]);

                }

                DynamicObjectCollection Efin = entity["AP_PAYABLEFIN"] as DynamicObjectCollection;
                DynamicObject FSettleType = Efin[0]["FSettleTypeID"] as DynamicObject;//结算方式 
                string jsfs1 = "";
                if (FSettleType != null)
                {
                    jsfs1 = Convert.ToString(FSettleType["Number"]);

                }


                DynamicObject FStocker = entity["F_RDLV_StockerID"] as DynamicObject;//仓管员 
                string cgy1 = "";
                if (FStocker != null)
                {
                    cgy1 = Convert.ToString(FStocker["Id"]);

                }
                DynamicObject FCarrier = entity["F_RDLV_CarrierID"] as DynamicObject;//承运商 
                string cys1 = "";
                if (FCarrier != null)
                {
                    cys1 = Convert.ToString(FCarrier["Number"]);

                }
                string ysdh1 = entity["F_RDLV_CarriageNO"].ToString();//运输单号

                //应收金额 ysje
                decimal ysje1 = Convert.ToDecimal(entity["FALLAMOUNTFOR"]);//应收金额

                DynamicObject FsaleBody = entity["F_RDLV_saleBody"] as DynamicObject;//销售主体 
                string xszt1 = "";
                if (FsaleBody != null)
                {
                    xszt1 = Convert.ToString(FsaleBody["Number"]);

                }

                string jcbm1 = entity["F_RDLV_JCBH"].ToString();//进仓编码jcbm

                string hxfs1 = entity["F_RDLV_WriteOff"].ToString();//核销方式

                string zfysd1 = "1"; //正负应收单
                if (ysje1 >= 0)
                {
                    zfysd1 = "1";
                }
                else
                {
                    zfysd1 = "0";
                }


                #endregion

                List<Datadetail> datadetails = new List<Datadetail>();

                //明细
                DynamicObjectCollection FEntity = entity["AP_PAYABLEENTRY"] as DynamicObjectCollection;

                foreach (DynamicObject Fe in FEntity)
                {
                    string FEntryId = Fe["ID"].ToString();//明细内码
                    string FSEQ = Fe["SEQ"].ToString();//行号

                    DynamicObject FStock = Fe["F_RDLV_Stock"] as DynamicObject;//仓库 
                    string ck1 = "";
                    if (FStock != null)
                    {
                        ck1 = Convert.ToString(FStock["Number"]);

                    }

                    string ydbs1 = "";//源单标识
                    string ydbm1 = "";//源单内码


                    DynamicObject FMATERIAL = Fe["MATERIALID"] as DynamicObject;//产品名称 
                    string cp11 = "";
                    string cp1 = "";
                    if (FMATERIAL != null)
                    {
                        cp11 = Convert.ToString(FMATERIAL["Name"]);
                        cp1 = Convert.ToString(FMATERIAL["Number"]);
                    }

                    decimal hsdj1 = Math.Round(Convert.ToDecimal(Fe["TaxPrice"]), 2); //含税单价

                    string sfzp1 = Convert.ToBoolean(Fe["IsFree"]) == true ? "1" : "0"; //是否赠品枚举：[0:否,1:是]

                    decimal sl1 = Convert.ToDecimal(Fe["EntryTaxRate"]); // 税率(%)

                    decimal xssl1 = Math.Round(Convert.ToDecimal(Fe["PriceQty"]), 2); // 销售数量

                    DynamicObject FLot = Fe["FLot"] as DynamicObject;//批次号 
                    string pch1 = "";
                    if (FLot != null)
                    {
                        pch1 = Convert.ToString(FLot["Number"]);

                    }

                    DynamicObject FPRICEUNIT = Fe["PRICEUNITID"] as DynamicObject;//销售单位 
                    string xsdw1 = "";
                    if (FPRICEUNIT != null)
                    {
                        xsdw1 = Convert.ToString(FPRICEUNIT["Number"]);

                    }
                    DynamicObject FSTOCKORG = Fe["FSTOCKORGID"] as DynamicObject;//库存组织 
                    string kczz1 = "";
                    if (FSTOCKORG != null)
                    {
                        kczz1 = Convert.ToString(FSTOCKORG["Number"]);

                    }

                    decimal jshj1 = Math.Round(Convert.ToDecimal(Fe["FALLAMOUNTFOR_D"]), 2); // 价税合计

                    //erp出库单内码 erpckdnm    varchar(99) detail1
                    //出库单明细内码 ckdmxnm varchar(99)	detail1
                    //基本数量    jbsl    decimal(38, 2)   detail1
                    //出库单号    ckdh varchar(99)	detail1
                    //本单折让金额  bdzrje  decimal(38, 2)   detail1
                    //累计折让金额  ljzrje  decimal(38, 2)   detail1



                    string ckdh1 = Fe["F_RDLV_OutBillNo"].ToString();//出库单号
                    decimal jbsl1 = Math.Round(Convert.ToDecimal(Fe["SalBaseQty"]), 2); // 基本数量
                    decimal bdzrje1 = Convert.ToDecimal(Fe["F_RDLV_DiscoutAmt"]); // 本单折让金额
                    decimal ljzrje1 = Convert.ToDecimal(Fe["F_RDLV_DiscoutAmtYTD"]); // 累计折让金额

                    Operate operate = new Operate()
                    {
                        action = "Save"
                    };
                    DetailData detailData = new DetailData()
                    {
                        ck = ck1,
                        ydbs = ydbs1,
                        ydbm = ydbm1,
                        ddmxxh = FEntryId,
                        cp1 = cp11,
                        hsdj = hsdj1,
                        sfzp = sfzp1,
                        sl = sl1,
                        xssl = xssl1,
                        pch = pch1,
                        xsdw = xsdw1,
                        jjdw = xsdw1,
                        kczz = kczz1,
                        jszz = jszz1,
                        cp = cp1,
                        jshj = jshj1,

                        ckdh = ckdh1,
                        jbsl = jbsl1,
                        bdzrje = bdzrje1,
                        ljzrje = ljzrje1




                    };
                    Datadetail datadetail = new Datadetail()
                    {
                        operate = operate,
                        data = detailData

                    };



                    datadetails.Add(datadetail);
                }


                #region 插入更新赋值
                mainTable mainTable1 = new mainTable()
                {
                    sfdc = sfdc1,
                    djnm = FID,
                    djbh = Number,
                    crmbm = crmbm1,
                    ddbh = ddbh1,
                    xsbm = xsbm1,
                    xsy = xsy1,
                    xszz = xszz1,
                    rq = rq1,
                    fhzz = fhzz1,
                    jszz = jszz1,
                    jhdd = jhdd1,
                    sfdhdd = sfdhdd1,
                    bz = bz1,
                    jsbb = jsbb1,
                    sfdz = sfdz1,
                    jhfs = jsfs1,
                    khmc = khmc1,
                    sktj = sktj1,
                    jsfs = jsfs1,
                    cgy = cgy1,
                    cys = cys1,
                    ysdh = ysdh1,
                    skzz = skzz1,
                    ysje = ysje1,
                    xszt = xszt1,
                    jcbm = jcbm1,
                    hxfs = hxfs1,
                    zfysd = zfysd1

                };


                //操作人员信息
                operationinfo operationinfo1 = new operationinfo()
                {
                    operatorAbAb = FCreator1,
                    operationDate = DateTime.Now.ToString("yyyy-MM-dd"),
                    operationTime = DateTime.Now.ToString("HH:mm:ss")
                };

                String currentTimeTamp = getTimestamp();
                String md5Source = httpSystemId + httpPassword + currentTimeTamp;
                String md5OfStr = Md5(md5Source).ToLower();


                Header header1 = new Header()
                {
                    systemid = httpSystemId,
                    currentDateTime = currentTimeTamp,
                    Md5 = md5OfStr
                };

                Data data = new Data()
                {
                    operationinfo = operationinfo1,
                    mainTable = mainTable1,
                    detail1 = datadetails
                };

                List<Data> datas = new List<Data>();
                datas.Add(data);


                DataHeader dataHeader = new DataHeader()
                {
                    data = datas,
                    header = header1
                };
                var json = JsonConvert.SerializeObject(dataHeader);
                json = json.ToString().Replace("operatorAbAb", "operator");
                #endregion

                #region 查询赋值
                ReceivableSelectModel.mainTable mainTable2 = new ReceivableSelectModel.mainTable()
                {
                    djnm = FID
                };
                //操作人员信息
                ReceivableSelectModel.operationinfo operationinfo2 = new ReceivableSelectModel.operationinfo()
                {
                    operatorAbAb = FCreator1,

                };
                ReceivableSelectModel.Header header2 = new ReceivableSelectModel.Header()
                {
                    systemid = httpSystemId,
                    currentDateTime = currentTimeTamp,
                    Md5 = md5OfStr
                };
                ReceivableSelectModel.DataHeader dataHeader1 = new ReceivableSelectModel.DataHeader()
                {
                    operationinfo = operationinfo2,
                    mainTable = mainTable2,
                    header = header2
                };

                var jsonS = JsonConvert.SerializeObject(dataHeader1);
                jsonS = jsonS.ToString().Replace("operatorAbAb", "operator");
                #endregion

                //查询是否存在
                var httpJson = GlobalParameters.PostToPushGroupNews(httpUrl + "/cube/restful/interface/getDataByPK/select_bill", jsonS);

                var arrresult = JsonConvert.DeserializeObject<SortedDictionary<string, object>>(httpJson);//转换
                var MainTable = JsonConvert.DeserializeObject<SortedDictionary<string, object>>(arrresult["result"].ToString());//转换


                if (MainTable.Count == 0)//
                {

                    var AddJson = GlobalParameters.PostToPushGroupNews(httpUrl + "/cube/restful/interface/saveOrUpdateModeData/create_bill", json);

                    var Addresult = JsonConvert.DeserializeObject<GlobalParameters.ReturnJson>(AddJson);//转换


                    if (Addresult.status == "1")
                    {
                        #region 应收单写日志(插入一张CRM接口日志单据，更新单据上的接口调用方式/调用时间/调用结果）
                        Common.InterfaceLog interfaceLog = new Common.InterfaceLog();
                        interfaceLog.FBILLNO = Number;
                        interfaceLog.FBILLID = FID;
                        interfaceLog.FDATE = System.DateTime.Now;
                        interfaceLog.FINTERNAME = " 应收单";
                        interfaceLog.FInvokeType = " 应收单新增";
                        interfaceLog.Ftoken = "";
                        interfaceLog.FSTATUS = "成功";
                        interfaceLog.FRequsetData = json.ToString();
                        interfaceLog.FReturnData = AddJson.ToString().Replace("'", "");
                        interfaceLog.FRequest = json.ToString();
                        interfaceLog.FReturn = AddJson.ToString().Replace("'", "");
                        string LogSql = interfaceLog.WriteCRMLogSql();//获取写入日志单据的SQL
                        List<string> sqlList = new List<string>();
                        if (!string.IsNullOrEmpty(LogSql))
                        {
                            sqlList.Add(LogSql);
                        }
                        //更新单据
                        string updateSql = string.Format(@"/*dialect*/ update t_AR_receivable set F_DEV_FDATE='{0}',F_DEV_FSTATUS='{1}' 
                    where FID={2}", interfaceLog.FDATE, interfaceLog.FSTATUS, FID);
                        sqlList.Add(updateSql);
                        DBServiceHelper.ExecuteBatch(ctx, sqlList);

                        #endregion
                    }
                    else
                    {
                        #region 应收单写日志(插入一张CRM接口日志单据，更新单据上的接口调用方式/调用时间/调用结果）
                        Common.InterfaceLog interfaceLog = new Common.InterfaceLog();
                        interfaceLog.FBILLNO = Number;
                        interfaceLog.FBILLID = FID;
                        interfaceLog.FDATE = System.DateTime.Now;
                        interfaceLog.FINTERNAME = "应收单";
                        interfaceLog.FInvokeType = "应收单新增";
                        interfaceLog.Ftoken = "";
                        interfaceLog.FSTATUS = "失败";
                        interfaceLog.FRequsetData = json.ToString();
                        interfaceLog.FReturnData = AddJson.ToString().Replace("'", "");
                        interfaceLog.FRequest = json.ToString();
                        interfaceLog.FReturn = AddJson.ToString().Replace("'", "");
                        string LogSql = interfaceLog.WriteCRMLogSql();//获取写入日志单据的SQL
                        List<string> sqlList = new List<string>();
                        if (!string.IsNullOrEmpty(LogSql))
                        {
                            sqlList.Add(LogSql);
                        }
                        //更新单据
                        string updateSql = string.Format(@"/*dialect*/ update t_AR_receivable set F_DEV_FDATE='{0}',F_DEV_FSTATUS='{1}' 
                    where FID={2}", interfaceLog.FDATE, interfaceLog.FSTATUS, FID);
                        sqlList.Add(updateSql);

                        DBServiceHelper.ExecuteBatch(ctx, sqlList);

                        #endregion
                    }

                }
                else
                {
                    //cube / restful /interface/saveOrUpdateModeData/update_Transportation_area
                    var UpdateJson = GlobalParameters.PostToPushGroupNews(httpUrl + "/cube/restful/interface/saveOrUpdateModeData/update_bill", json);

                    var Updateresult = JsonConvert.DeserializeObject<GlobalParameters.ReturnJson>(UpdateJson);//转换

                    if (Updateresult.status == "1")
                    {
                        #region 应收单写日志(插入一张CRM接口日志单据，更新单据上的接口调用方式/调用时间/调用结果）
                        Common.InterfaceLog interfaceLog = new Common.InterfaceLog();
                        interfaceLog.FBILLNO = Number;
                        interfaceLog.FBILLID = FID;
                        interfaceLog.FDATE = System.DateTime.Now;
                        interfaceLog.FINTERNAME = "应收单";
                        interfaceLog.FInvokeType = "应收单更新";
                        interfaceLog.Ftoken = "";
                        interfaceLog.FSTATUS = "成功";
                        interfaceLog.FRequsetData = json.ToString();
                        interfaceLog.FReturnData = UpdateJson.ToString().Replace("'", "");
                        interfaceLog.FRequest = json.ToString();
                        interfaceLog.FReturn = UpdateJson.ToString().Replace("'", "");
                        string LogSql = interfaceLog.WriteCRMLogSql();//获取写入日志单据的SQL
                        List<string> sqlList = new List<string>();
                        if (!string.IsNullOrEmpty(LogSql))
                        {
                            sqlList.Add(LogSql);
                        }
                        //更新单据
                        string updateSql = string.Format(@"/*dialect*/ update t_AR_receivable set F_DEV_FDATE='{0}',F_DEV_FSTATUS='{1}' 
                    where FID={2}", interfaceLog.FDATE, interfaceLog.FSTATUS, FID);
                        sqlList.Add(updateSql);
                        DBServiceHelper.ExecuteBatch(ctx, sqlList);

                        #endregion
                    }
                    else
                    {
                        #region 应收单写日志(插入一张CRM接口日志单据，更新单据上的接口调用方式/调用时间/调用结果）
                        Common.InterfaceLog interfaceLog = new Common.InterfaceLog();
                        interfaceLog.FBILLNO = Number;
                        interfaceLog.FBILLID = FID;
                        interfaceLog.FDATE = System.DateTime.Now;
                        interfaceLog.FINTERNAME = "应收单";
                        interfaceLog.FInvokeType = "应收单更新";
                        interfaceLog.Ftoken = "";
                        interfaceLog.FSTATUS = "失败";
                        interfaceLog.FRequsetData = json.ToString();
                        interfaceLog.FReturnData = UpdateJson.ToString().Replace("'", "");
                        interfaceLog.FRequest = json.ToString();
                        interfaceLog.FReturn = UpdateJson.ToString().Replace("'", "");
                        string LogSql = interfaceLog.WriteCRMLogSql();//获取写入日志单据的SQL
                        List<string> sqlList = new List<string>();
                        if (!string.IsNullOrEmpty(LogSql))
                        {
                            sqlList.Add(LogSql);
                        }
                        //更新单据
                        string updateSql = string.Format(@"/*dialect*/ update t_AR_receivable set F_DEV_FDATE='{0}',F_DEV_FSTATUS='{1}' 
                    where FID={2}", interfaceLog.FDATE, interfaceLog.FSTATUS, FID);

                        sqlList.Add(updateSql);

                        DBServiceHelper.ExecuteBatch(ctx, sqlList);
                        #endregion
                    }

                }
            }
        }

        /// <summary>
        /// api配置
        /// </summary>
        public DataTable APISetting(Context ctx)
        {
            string Sql = string.Format(@"select * from RDLV_t_CRMInterface");
            return DBServiceHelper.ExecuteDataSet(ctx, Sql).Tables[0];

        }

        /// <summary>
        /// md5加密
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static String Md5(string s)
        {
            char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(s);
            byte[] result = md5.ComputeHash(inputBytes);
            int j = result.Length;
            char[] str = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++)
            {
                byte byte0 = result[i];
                str[k++] = hexDigits[byte0 >> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        }
        /**
       * 获取时间戳   格式如：19990101235959
       * @return
       */
        public static String getTimestamp()
        {

            return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss").Replace("-", "").Replace(":", "").Replace(" ", "").Replace("/", "");
        }



    }
}
